#include <stddef.h>
#include <stdio.h>

void test1() {
    int a = 10;
    int *p = &a;                         // 将变量a的地址赋值给指针p
    printf("a的地址：%p\n", p);          // 0x7ff7bd6b4c2c
    printf("a的地址：%p\n", &a);         // 0x7ff7bd6b4c2c
    printf("a的值：%d\n", *p);           // 10
    printf("移动地址地址：%p\n", p + 1); // 0x7ff7bf721c30

    int arr[] = {1, 2, 3, 4, 5};
    p = arr;
    int *p1 = &arr[5];
    ptrdiff_t diff = p1 - p;
    printf("想差几个元素：%zd\n", diff); // 5
}

void test2() {
    int a[] = {1, 2, 3, 4, 5};
    int *p;
    p = &a[0];
    printf("p的地址：%p\n", p); // p的地址：0x7ff7b095fc10
    p = a;
    printf("p的地址：%p\n", p); // p的地址：0x7ff7b095fc10
}

/**
 * 数组的赋值及遍历
 */
void test3() {
    int N = 5;
    int a[5];

    // 方式一：
    printf("请输出%d个整数\n", N);
    for (int i = 0; i < N; i++) {
        scanf("%d", &a[i]);
    }
    for (int i = 0; i < N; i++) {
        printf("%d\n", a[i]);
    }

    // 方式二：
    printf("方式二请输出%d个整数\n", N);
    for (int i = 0; i < N; i++) {
        scanf("%d", (a + i));
    }
    for (int i = 0; i < N; i++) {
        printf("%d\n", *(a + i));
    }

    // 方式三：
    printf("方式三请输出%d个整数\n", N);
    for (int *p = a; p < a + N; p++) {
        scanf("%d", p);
    }
    for (int *p = a; p < a + N; p++) {
        printf("%d\n", *p);
    }
}

/**
 * 测试指针以数组的方式访问
 */
void test4() {
    int a[] = {1, 2, 3, 4, 5};
    int *p = a;
    for (int i = 0; i < 5; i++) {
        printf("%d\n", p[i]);
    }
    p = a + 2;
    printf("%d\n", p[2]); // 5
}

void test5() {
    int a[5] = {0};
    int *p = a;
    printf("%p\n", a);     // 0x7ff7b88b4c10
    printf("%p\n", &a);    // 0x7ff7b88b4c10
    printf("%p\n", p);     // 0x7ff7b88b4c10
    printf("%p\n", a + 1); // 0x7ff7b88b4c14 表示下一个元素的地址，刚好4个字节
    printf("%p\n",
           &a + 1); // 0x7ff7b88b4c24 表示整个数组结束后下一个地址，刚好是
                    // 20个字节。16进行的16就是十进制的20
}

int main() {
    int a[3][4] = {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}};
    // 0行0列元素的地址
    printf("%p\n", &a[0][0]); // 0x7ff7b292bbf0
    printf("%p\n", a[0]);     // 0x7ff7b292bbf0
    printf("%p\n", a);        // 0x7ff7b292bbf0
    printf("%p\n", *a);       // 0x7ff7b292bbf0
    // 0行0列元素的值
    printf("%d\n", a[0][0]);
    printf("%d\n", *(a[0]));
    printf("%d\n", *(*a));
    // 指向索引为1行的起始地址
    printf("%p\n", &a[1]);     // 0x7ff7bdcc8c00
    printf("%p\n", &a[0] + 1); // 0x7ff7bdcc8c00
    printf("%p\n", a + 1);     // 0x7ff7bdcc8c00
    // 1行0列元素 a[1][0]的地址
    printf("%p\n", &a[1][0]); // 0x7ff7b3a40c00
    printf("%p\n", a[1]);     // 0x7ff7b3a40c00
    printf("%p\n", *(a + 1)); // 0x7ff7b3a40c00
    return 0;
}